package utils;

/**
 * 节点类
 * @author 车宗绍Che Zongshao
 * @date 2015/1/7
 */

public class Node {

	private int name;			// 节点名: A1, B2, C3, D4, E5
	private Edge[] nextEdges;	// 邻接边
	private Node father;		// 父节点
	private double fn;			// f(n)
	private double gn;			// g(n)
	private Byte bitmap;		// 记录当前路径已经访问过的节点的map
	
	/**
	 * 得到节点在路径中的位置
	 * @return
	 */
	public int getPosition() {
		return ((bitmap >> 4) & 0x1) + ((bitmap >> 3) & 0x1) 
				+ ((bitmap >> 2) & 0x1) + ((bitmap >> 1) & 0x1) 
				+ (bitmap & 0x1);
	}
	
	/**
	 * 用name生成Byte
	 * @param name
	 * @return Byte
	 */
	public static Byte generateByte(int name) {
		if (name >= 1 && name <= 6) {
			// A:1 ~ F:6
			return Byte.valueOf((byte) (1 << (name-1)));
		}
		return null;
	}
	
	/**
	 * 边被使用过吗?
	 * @param endName
	 * @return true: 边被用过; false: 边没被用过
	 */
	public boolean isEdgeUsed(int endName) {
		if (((this.bitmap >> (endName-1)) & 0x1) == 1) {
			return true;
		} else {
			return false;
		}
	}
	
	public Node() {}
	
	public Node(int name) {
		this.name = name;
	}
	/**
	 * 扩展Node
	 * @param father
	 * @param name
	 */
	public Node(Node father, int name) {
		Node son = Graph.generateNode(name);
		this.name = son.getName();
		this.nextEdges = son.getNextEdges();
		this.father = father;
		this.gn = father.getGn() + father.getEdge(name).getLength();
		this.bitmap = (byte) (father.getBitmap() | Node.generateByte(name));
	}
	
	/**
	 * 用endName得到Edge
	 * @param endName
	 * @return Edge
	 */
	public Edge getEdge(int endName) {
		for (int i = 0; i < this.nextEdges.length; i++) {
			if (this.nextEdges[i].getEnd().getName() == endName) {
				return nextEdges[i];
			}
		}
		return null;
	}
	public int getName() {
		return name;
	}
	public void setName(int name) {
		this.name = name;
	}
	public Edge[] getNextEdges() {
		return nextEdges;
	}
	public void setNextEdges(Edge[] nextEdges) {
		this.nextEdges = nextEdges;
	}
	public Node getFather() {
		return father;
	}
	public void setFather(Node father) {
		this.father = father;
	}
	public double getFn() {
		return fn;
	}
	public void setFn(double fn) {
		this.fn = fn;
	}
	public double getGn() {
		return gn;
	}
	public void setGn(double gn) {
		this.gn = gn;
	}
	public Byte getBitmap() {
		return bitmap;
	}
	public void setBitmap(Byte bitmap) {
		this.bitmap = bitmap;
	}
	
}